# -*- coding: utf-8 -*-
import logging
import os
import random
import time
from traceback import format_exc
from scrapy.utils.project import get_project_settings
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from zc_core.middlewares.proxies.cached_pool import CachedProxyPool
from zc_core.plugins.verify_code import VerifyCode
from zc_core.util.instance_builder import build_instance


class SimpleSession(object):
    cookies = None
    # 登录地址
    login_home = 'http://b.ctaxccgp.com.cn/'
    login_page = 'http://login.ctaxccgp.com.cn/supermarket/loginPage'
    login_url = 'http://login.ctaxccgp.com.cn/supermarket/loginPage?userType=1'
    index_url = 'http://b.ctaxccgp.com.cn/firstZoneIndex/index.htm'
    cookie_white_list = ['__s_f_c_s_', '__d_s_', '__t_c_k_', 'JSESSIONID']

    def __init__(self, timeout=180):
        settings = get_project_settings()
        self.max_login_retry = settings.get('MAX_LOGIN_RETRY', 3)
        self.accounts = settings.get('ACCOUNTS', [])
        self.timeout = timeout

    def new_chrome(self):
        self.option = webdriver.ChromeOptions()
        # self.option.add_argument('--headless')
        self.option.add_argument('--no-sandbox')
        # 构建校验器对象
        # settings = get_project_settings()
        # proxy_pool_class = settings.get('PROXY_POOL_CLASS', '')
        # if proxy_pool_class:
        #     self.pool = build_instance(proxy_pool_class, settings)
        # else:
        #     self.pool = CachedProxyPool(settings)
        # self.option.add_argument('--proxy-server=http://%s' % self.pool.get_proxy())

        self.browser = webdriver.Chrome(chrome_options=self.option)
        self.browser.set_window_size(1400, 700)
        self.browser.set_page_load_timeout(self.timeout)

    def login(self):
        try:
            self.new_chrome()
            self.browser.get(self.login_home)
            time.sleep(3)
            self.browser.find_element_by_class_name('login-div').click()
            time.sleep(3)
            self.browser.get(self.login_url)

            # account = random.choice(self.accounts)
            account = {'yhb113820': '13453186180a'}
            logging.info('login account: %s' % account)

            username = self.browser.find_element_by_id("username")
            username.clear()
            username.send_keys(list(account.keys())[0])
            time.sleep(1)

            password = self.browser.find_element_by_id("password")
            password.clear()
            password.send_keys(list(account.values())[0])
            time.sleep(1)

            # ------------------------------------------
            # 识别验证码
            code = self._verify_code(self.browser.find_element_by_id("personSecurityCode"))
            if code:
                # 验证码
                verify = self.browser.find_element_by_id("person_reg_security")
                verify.clear()
                verify.send_keys(code)
                time.sleep(1)

                # 登录
                submit = self.browser.find_element_by_class_name("login-btn")
                submit.click()
                time.sleep(10)

                # 刷新
                self.browser.refresh()
                time.sleep(3)
                # 刷新
                self.browser.refresh()
                time.sleep(5)

                # 校验
                # http://b.ctaxccgp.com.cn/homeIndex/index.htm?author=Magical+Sam
                WebDriverWait(self.browser, 15).until(EC.url_contains('b.ctaxccgp.com'))
                cookies = self.browser.get_cookies()
                logging.info('--> origin cookies: %s' % cookies)

                self.browser.close()
                return cookies
            # ------------------------------------------
        except Exception as e:
            _ = e
            logging.error(format_exc())
            self.browser.close()
            return list()

    def _verify_code(self, element):
        """
        截取指定元素图片
        :param element: 元素对象
        :return: 无
        """
        """图片路径"""
        settings = get_project_settings()
        base_path = os.path.join(settings.get('IMAGES_STORE'), 'verify_code/')
        if not os.path.exists(base_path):
            os.makedirs(base_path)
        file = os.path.join(base_path, '%s.png' % str(time.strftime('%Y%m%d%H%M%S')))
        element.screenshot(file)

        """保存识别结果"""
        # 1004: 四位数字英文混合
        code = VerifyCode().verify(file, code_type='1004')
        if code:
            new_file = os.path.join(base_path, '%s.png' % code)
            os.rename(file, new_file)
            return code

    # cookie获取
    def get_cookies(self):
        if not self.cookies:
            self.cookies = self.__get_cookies(0)
            logging.info('--> login cookie: %s' % self.cookies)
        return self.cookies

    def clean_cookies(self):
        self.cookies = None

    # 最大重试登录获取cookie
    def __get_cookies(self, retry):
        # 登录获取
        arr = self.login()
        if not arr:
            # 失败重试
            if retry <= self.max_login_retry:
                retry = retry + 1
                logging.info('--> 登录失败重试: %s次' % retry)
                return self.__get_cookies(retry)
            else:
                logging.info('--> 放弃失败重试: %s次' % retry)
                return dict()

        # 重组、白名单过滤
        cookies = dict()
        for cookie in arr:
            cookie_key = cookie.get('name')
            if cookie_key in self.cookie_white_list:
                cookies[cookie_key] = cookie.get('value')

        # 校验
        if not cookies or not self._validate_cookie(cookies):
            # 失败重试
            if retry <= self.max_login_retry:
                retry = retry + 1
                logging.info('--> 登录失败重试: %s次' % retry)
                return self.__get_cookies(retry)
            else:
                logging.info('--> 放弃失败重试: %s次' % retry)
                return dict()

        logging.info('--> 登录成功: %s次' % retry)
        return cookies

    # cookie校验
    def _validate_cookie(self, cookies):
        for must_key in self.cookie_white_list:
            # 必要字段校验
            if not cookies or (must_key not in cookies) or (cookies.get(must_key) is None) or (
                    cookies.get(must_key) == ''):
                logging.info('--> Cookie未通过校验: key=%s, cookie=%s' % (must_key, cookies))
                return False

        return True
